package admin

import (
	"context"
	"database/sql"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/util/gconv"
	"miaoyu/internal/dao"
	modelAdmin "miaoyu/internal/model/admin"
	"miaoyu/internal/model/entity"
	"miaoyu/internal/service"
	"miaoyu/internal/utility"
	"strings"
)

type sUser struct{}

var user = sUser{}

func init() {
	service.RegisterUser(NewUser())
}
func NewUser() *sUser {
	return &sUser{}
}
func (s *sUser) GetPageList(ctx context.Context, options modelAdmin.CommonListInput) (list []modelAdmin.UserItemOutput, count int, err error) {
	var condition g.MapStrAny
	var pageLimit modelAdmin.PageLimit
	if options.Keywords != "" {
		condition = make(g.MapStrAny)
		condition["title like ?"] = "%" + options.Keywords + "%"
	}
	pageLimit.Start = (options.Page - 1) * options.Limit
	pageLimit.Limit = options.Limit

	resList, resCount, resErr := dao.MyUser.GetPageList(ctx, condition, pageLimit)

	if resErr != nil {
		err = resErr
		return
	}
	count = resCount

	scanErr := gconv.Scan(resList, &list)
	if scanErr != nil {
		err = gerror.New("获取数据错误")
		return
	}

	return
}
func (s *sUser) checkSubmit(ctx context.Context, data modelAdmin.UserSubmitInput, action string) (err error) {
	//检查是否有重复的用户名
	data.UserName = strings.Trim(data.UserName, " ")
	conditionUser := g.MapStrAny{}
	conditionPhone := g.MapStrAny{}
	if action == "edit" {
		conditionUser["id <> ?"] = data.ResId
		conditionPhone["id <> ?"] = data.ResId
		conditionUser["user_name"] = data.UserName
		conditionPhone["phone"] = data.Phone
	} else {
		conditionUser["user_name"] = data.UserName
		conditionPhone["phone"] = data.Phone
	}

	if data.UserName == "" {
		err = gerror.New("用户名不能为空")
		return
	}
	if action == "add" && (strings.Trim(data.Password, " ") == "") {
		err = gerror.New("密码处不能为空")
		return
	}
	_, resErr := dao.MyUser.GetItem(ctx, conditionUser)
	if resErr != nil && resErr != sql.ErrNoRows {
		g.Log().Error(ctx, "检查用户信息失败", data.UserName)
		err = gerror.New("数据获取错误")
		return
	}
	if resErr != sql.ErrNoRows {
		err = gerror.New("该用户名已存在")
		return
	}
	_, resErr = dao.MyUser.GetItem(ctx, conditionPhone)
	if resErr != nil && resErr != sql.ErrNoRows {
		g.Log().Error(ctx, "检查用户信息失败", data.UserName)
		err = gerror.New("数据获取错误")
		return
	}
	if resErr != sql.ErrNoRows {
		err = gerror.New("该手机号已存在，请更换手机号")
		return
	}
	return
}
func (s *sUser) GetItemById(ctx context.Context, id int64) (res entity.MyUser, resErr error) {
	res, resErr = dao.MyUser.GetItemById(ctx, id)
	if resErr != nil && resErr != sql.ErrNoRows {
		resErr = gerror.New("检索错误")
		return
	}
	if resErr == sql.ErrNoRows {
		resErr = gerror.NewSkip(404, "数据不存在")
		return
	}
	return
}
func (s *sUser) Grant(ctx context.Context, userId int64, roleIdList []int64) (res sql.Result, err error) {
	roleLength := len(roleIdList)
	grantList := make([]entity.MyUserRole, roleLength)

	for key, ele := range roleIdList {
		grantList[key] = entity.MyUserRole{RoleId: ele, UserId: userId}
	}
	_, delErr := dao.MyUserRole.DeleteByUserId(ctx, userId)
	if delErr != nil {
		err = delErr
		return
	}
	res, err = dao.MyUserRole.GrantRoleToUser(ctx, grantList)

	if err != nil {
		return
	}
	//更新casbin策略库

	service.Access().UpdateUserRole(ctx, userId, roleIdList)

	return
}
func (s *sUser) Add(ctx context.Context, options modelAdmin.UserSubmitInput) (res sql.Result, err error) {
	checkErr := s.checkSubmit(ctx, options, "add")
	if checkErr != nil {
		err = checkErr
		return
	}
	options.Password = utility.MakeAdminPassWord(options.Password)
	var user entity.MyUser
	err = gconv.Scan(options, &user)
	res, err = dao.MyUser.Add(ctx, user)
	if err != nil {
		return
	}
	return
}
func (s *sUser) Edit(ctx context.Context, options modelAdmin.UserSubmitInput, resId int64) (res sql.Result, err error) {
	//options.UserName ####################
	checkErr := s.checkSubmit(ctx, options, "edit")
	if checkErr != nil {
		err = checkErr
		return
	}
	if options.Password != "zhanweifu" {
		options.Password = utility.MakeAdminPassWord(options.Password)

	} else {
		options.Password = ""
	}
	var user entity.MyUser
	err = gconv.Scan(options, &user)
	if options.Password == "" {
		res, err = dao.MyUser.UpdateItemById(ctx, user, resId)
	} else {
		res, err = dao.MyUser.UpdateItemByIdWitPassword(ctx, user, resId)
	}

	if err != nil {
		return
	}

	return
}

func (s *sUser) Del(ctx context.Context, resId int64) (sqlAffectRows int64, err error) {

	sqlAffectRows, err = dao.MyUser.DeleteItemById(ctx, resId)
	if err != nil {
		err = gerror.NewSkip(404, "角色删除失败")
		return
	}
	if sqlAffectRows == 0 {
		err = gerror.New("请求的信息不存在")
		return
	}

	return
}
